package com.wx.lambda.ii.chapter6;

import com.wx.lambda.ii.chapter4.Chapter4Test;
import com.wx.lambda.ii.chapter4.Dish;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static java.util.Comparator.comparingInt;
import static  java.util.stream.Collectors.*;


/**
 * 第六章测试
 */
@Slf4j
public class Chapter6Test {
    public static void main(String[] args) {
        List<Dish> dishes = Chapter4Test.initData();

        dishes.stream().collect(Collectors.toList());

        Long count1 = dishes.stream().collect(counting());
        long count2 = dishes.stream().count();
        log.info("count1={},count2={}", count1, count2);
        // 最大值， 最小值
        Comparator<Dish> comparing = Comparator.comparing(Dish::getCalories);
        Optional<Dish> max1 = dishes.stream().collect(maxBy(comparing));
        Optional<Dish> max2 = dishes.stream().max(comparing);
        log.info("max1={},max2={}", max1.get().getCalories(), max2.get().getCalories());
        // 平均值，总数
        Long sumCalories = dishes.stream().collect(summingLong(Dish::getCalories));
        log.info("sumCalories={}", sumCalories);
        Double avgCalories = dishes.stream().collect(averagingLong(Dish::getCalories));
        log.info("avgCalories={}", avgCalories);
        // 统计
        IntSummaryStatistics summaryStatistics = dishes.stream().collect(summarizingInt(Dish::getCalories));
        log.info("所有的统计 summaryStatistics={}", summaryStatistics);
        // 拼接 菜单名字
        String dishNames = dishes.stream().map(Dish::getName).collect(joining(","));
        log.info("dishNames={}", dishNames);
        // 利用reducing 拼接 菜单名字
        String dishNames2 = dishes.stream().collect(reducing("", Dish::getName, (s1, s2) -> s1 + "," + s2));
        log.info("dishNames2={}", dishNames2);
        // 分组
        Map<Dish.Type, List<Dish>> groupByType = dishes.stream().collect(groupingBy(Dish::getType));
        log.info("groupByType{}", groupByType);
        // 按照热量分组
        Map<String, List<Dish>> groupByCalories = dishes.stream().collect(groupingBy(dish -> {
            if (dish.getCalories() > 400) {
                return "high";
            } else if (dish.getCalories() > 300) {
                return "medium";
            } else {
                return "low";
            }

        }));
        log.info("按照热量进行分组 groupByCalories={}", groupByCalories);
        // 二级分组
        Map<Dish.Type, Map<String, List<Dish>>> secondGroupBy = dishes.stream().collect(groupingBy(Dish::getType, groupingBy(dish -> {
            if (dish.getCalories() > 400) {
                return "high";
            } else if (dish.getCalories() > 300) {
                return "medium";
            } else {
                return "low";
            }
        })));
        log.info("二级分组 secondGroupBy={}", secondGroupBy);
        // 分区
        Map<Boolean, String> partition = dishes.stream().collect(
                partitioningBy(Dish::isVegetarian,
                        collectingAndThen(
                                maxBy(comparingInt(Dish::getCalories)), (Optional<Dish> max) -> max.get().getName())));
        log.info("partition={}", partition);


        // 质数
        primeNumber(100);
    }

    /**
     * 给定一个最大数，挑选出 所有的质数和合数
     * @param n
     */
    static void primeNumber(int n){
        Map<Boolean, List<Integer>> prime = IntStream.range(2, n).boxed().collect(partitioningBy(Chapter6Test::isPan));
        log.info("prime={}", prime);


    }

    private static boolean isPan(int n) {
        //int sqrt = (int) Math.sqrt(n);
        return IntStream.range(2, n).noneMatch(i -> n % i == 0);
    }

}
